<?php
/*********************************************
  CPG Dragonfly™ CMS
  ********************************************
  Copyright © 2004 - 2007 by CPG-Nuke Dev Team
  http://dragonflycms.org

  Dragonfly is released under the terms and conditions
  of the GNU GPL version 2 or any later version
**********************************************/
if (!defined('ADMIN_PAGES')) { exit; }
if (!can_admin('blocks')) { die('Access Denied'); }

Dragonfly::getKernel()->L10N->load('dragonfly/blocks');

Dragonfly_Page::setTitle(Dragonfly::getKernel()->L10N->get('Blocks'));

class Dragonfly_Blocks_Block
{
	protected
		$data = array(
			'bid'       => 0,
			'bkey'      => '',
			'title'     => '',
			'content'   => '',
			'url'       => '',
			'active'    => true,
			'refresh'   => 3600,
			'time'      => 0, // varchar ??
			'blanguage' => '',
			'blockfile' => '',
			'view'      => 0,
			// old system
			'bposition' => '', // l=left, c=center-top, d=center-bottom, r=right
			'in_module' => '',
			'weight'    => 0,
		),
		$oldposition;

	function __construct($bid=0)
	{
		$bid = intval($bid);
		if ($bid)
		{
			$SQL = Dragonfly::getKernel()->SQL;
			if ($data = $SQL->uFetchAssoc("SELECT * FROM {$SQL->TBL->blocks} WHERE bid={$bid}"))
			{
				$this->data['bid'] = $bid;
				foreach ($data as $k => $v) { $this->__set($k, $v); }
				$this->oldposition = $this->data['bposition'];
			}
		}
	}

	function __get($k)
	{
		if ('data'===$k) { return $this->data; }
		if ('label'===$k) {
			return (defined($this->data['title']) ? constant($this->data['title']) : str_replace('_', ' ',$this->data['title']));
		}
		if (array_key_exists($k, $this->data))  { return $this->data[$k]; }
		trigger_error("Property '{$k}' does not exist");
	}

	function __set($k, $v)
	{
		if ('bid'===$k) { return; }
		if (array_key_exists($k, $this->data)) {
			if (is_int($this->data[$k])) {
				$this->data[$k] = intval($v);
			} else if (is_bool($this->data[$k])) {
				$this->data[$k] = !!$v;
			} else {
				$this->data[$k] = trim($v);
			}
		} else {
			trigger_error("Property '{$k}' does not exist");
		}
	}

	public function save()
	{
		if ($this->data['blockfile']) {
			$this->data['bkey'] = 'file';
			if (!$this->data['title']) {
				$this->data['title'] = str_replace('_',' ',preg_replace('#(block-|\.php)#','',$this->data['blockfile']));
			}
		} else if ($this->data['url']) {
			$this->data['bkey'] = 'rss';
			$this->data['time'] = time();
			$url = $this->data['url'];
			if (!preg_match('#https?://#',$url)) { $url = 'http://'.$url; }
			require_once(CORE_PATH.'classes/rss.php');
			if (!($this->data['content'] = CPG_RSS::format(CPG_RSS::read($url)))) {
				throw new Exception(Dragonfly::getKernel()->L10N->get('There seems to be a problem with the URL for this feed'));
			}
			$this->data['url'] = $url;
		} else {
			$this->data['bkey'] = 'custom';
		}
		if (!$this->data['content'] && !$this->data['blockfile']) { return false;	}

		$SQL = Dragonfly::getKernel()->SQL;
		$tbl = $SQL->TBL->blocks;
		if ($this->data['bid'])
		{
			# can be removed
			if ($this->oldposition != $this->data['bposition']) {
				$SQL->exec("UPDATE {$SQL->TBL->blocks} SET weight=weight+1 WHERE weight>={$this->data['weight']} AND bposition='{$this->data['bposition']}'");
				$SQL->exec("UPDATE {$SQL->TBL->blocks} SET weight=weight-1 WHERE weight>{$this->data['weight']} AND bposition='{$this->oldposition}'");
			}
			# end
			$tbl->update($this->data, 'bid='.$this->data['bid']);
		}
		else
		{
			# might be removed later on
			list($weight) = $SQL->uFetchRow("SELECT weight FROM {$SQL->TBL->blocks} WHERE bposition='{$this->data['bposition']}' ORDER BY weight DESC");
			$this->data['weight'] = $weight+1;
			# end
			$data = $this->data;
			unset($data['bid']);
			$this->data['bid'] = $tbl->insert($data, 'bid');
			$this->oldposition = $this->data['bposition'];
		}
		//Dragonfly::getKernel()->CACHE->delete('blocks_list');
		return true;
	}

	public function delete()
	{
		if ($this->data['bid']) {
			$SQL = Dragonfly::getKernel()->SQL;
			$SQL->TBL->blocks->delete("bid={$this->data['bid']}");
			$SQL->TBL->blocks_custom->delete("bid={$this->data['bid']}");
			$SQL->exec("UPDATE {$SQL->TBL->blocks} SET weight=weight-1 WHERE weight>{$this->data['weight']} AND bposition='{$this->data['bposition']}'");
			//Dragonfly::getKernel()->CACHE->delete('blocks_list');
			$this->data['bid'] = 0;
		}
	}

	public function getFileOptions()
	{
		$selblocks = array();
		$blocksdir = dir('blocks');
		while ($func = $blocksdir->read()) {
			if (preg_match('#block-(.*).php$#', $func, $m)) {
				$selblocks[strtoupper($func)] = array(
					'value' => $func,
					'label' => str_replace(array('-','_'),' ',$m[1]),
					'selected' => ($func == $this->data['blockfile']),
				);
			}
		}
		closedir($blocksdir->handle);
		ksort($selblocks);
		return $selblocks;
	}

	public function getPositionOptions()
	{
		$L10N = Dragonfly::getKernel()->L10N;
		return array(
			array(
				'value' => 'l',
				'label' => $L10N->get('Left'),
				'selected' => ('l' == $this->data['bposition']),
			),
			array(
				'value' => 'c',
				'label' => $L10N->get('Center Up'),
				'selected' => ('c' == $this->data['bposition']),
			),
			array(
				'value' => 'd',
				'label' => $L10N->get('Center Down'),
				'selected' => ('d' == $this->data['bposition']),
			),
			array(
				'value' => 'r',
				'label' => $L10N->get('Right'),
				'selected' => ('r' == $this->data['bposition']),
			),
		);
	}

	public function getRefreshOptions()
	{
		$L10N = Dragonfly::getKernel()->L10N;
		return array(
			array(
				'value' => 1800,
				'label' => $L10N->timeReadable(1800),
				'selected' => (1800 == $this->data['refresh']),
			),
			array(
				'value' => 3600,
				'label' => $L10N->timeReadable(3600),
				'selected' => (3600 == $this->data['refresh']),
			),
			array(
				'value' => 10800,
				'label' => $L10N->timeReadable(10800),
				'selected' => (10800 == $this->data['refresh']),
			),
			array(
				'value' => 21600,
				'label' => $L10N->timeReadable(21600),
				'selected' => (21600 == $this->data['refresh']),
			),
			array(
				'value' => 43200,
				'label' => $L10N->timeReadable(43200),
				'selected' => (43200 == $this->data['refresh']),
			),
			array(
				'value' => 86400,
				'label' => $L10N->timeReadable(86400),
				'selected' => (86400 == $this->data['refresh']),
			),
		);
	}

	public function getViewOptions()
	{
		static $groups;
		if (!$groups) {
			$groups = array(
				0=>array('id'=>0, 'label'=>Dragonfly::getKernel()->L10N->get('All Visitors'),   'selected'=>0==$this->data['view']),
				3=>array('id'=>3, 'label'=>Dragonfly::getKernel()->L10N->get('Anonymous'),  'selected'=>3==$this->data['view']),
				2=>array('id'=>2, 'label'=>Dragonfly::getKernel()->L10N->get('Administrators'), 'selected'=>2==$this->data['view']),
				1=>array('id'=>1, 'label'=>Dragonfly::getKernel()->L10N->get('Members'), 'selected'=>1==$this->data['view']),
			);
			$SQL = Dragonfly::getKernel()->SQL;
			$qr = $SQL->query("SELECT group_id, group_name FROM {$SQL->TBL->bbgroups} WHERE group_single_user=0");
			while ($r = $qr->fetch_row()) {
				$groups[($r[0]+3)] = array(
					'id'=>$r[0]+3, 'label'=>$r[1], 'selected'=>$r[0]+3==$this->data['view']
				);
			}
		}
		return $groups;
	}

}

if (isset($_GET['change']))
{
	$block = new Dragonfly_Blocks_Block($_GET['change']);
	if ($block->bid) {
		$block->active = !$block->active;
		$block->save();
	}
	URL::redirect(URL::admin('blocks'));
}

else if (isset($_GET['show'])) {
	block_show(intval($_GET['show']));
}

else if (isset($_GET['edit'])) {
	if (Security::check_post()) {
		BlocksEditSave($_GET['edit']);
	}
	BlocksEdit($_GET['edit']);
}

else if (isset($_GET['del'])) {
	if (isset($_POST['cancel'])) { URL::redirect(URL::admin()); }
	$block = new Dragonfly_Blocks_Block($_GET['del']);
	if (isset($_POST['confirm'])) {
		$block->delete();
		//Dragonfly::getKernel()->CACHE->delete('blocks_list');
		URL::redirect(URL::admin());
	}
	cpg_delete_msg(URL::admin('&amp;del='.$block->bid), sprintf(Dragonfly::getKernel()->L10N->get('Are you sure that you want to delete %s?'), $block->label));
}

else {
	if (isset($_POST['add']) && Security::check_post()) {
		BlocksEditSave(0);
		return;
	}

	if (isset($_POST['mid']) && Security::check_post())
	{
		$mid = intval($_POST['mid']);

		if (0<$mid) {
			$blocks = empty($_POST['module_blocks']) ? 0 : array_sum($_POST['module_blocks']);
			$db->exec("UPDATE {$db->TBL->modules} SET blocks={$blocks} WHERE mid={$mid}");
		}

		$db->query("DELETE FROM {$db->TBL->blocks_custom} WHERE mid={$mid}");
		foreach ($_POST['side'] as $side => $bids) {
			$bids = array_values($bids);
			foreach ($bids as $weight => $bid) {
				$db->TBL->blocks_custom->insert(array(
					'bid' => $bid,
					'mid' => $mid,
					'side' => $side,
					'weight' => $weight+1
				));
			}
		}

		if (XMLHTTPRequest) { exit; }
		//Dragonfly::getKernel()->CACHE->delete('blocks_list');
		URL::redirect(URL::admin('blocks'));
	}

	BlocksAdmin();
}

function BlocksAdmin()
{
	Dragonfly_Output_Css::add('adminblocks');
	Dragonfly_Output_Js::add('themes/admin/javascript/adminblocks.js');

	Dragonfly_Output_Js::add('includes/poodle/javascript/bbcode.js');
	Dragonfly_Output_Css::add('bbcode');

	$K   = Dragonfly::getKernel();
	$L10N = $K->L10N;
	$TPL  = $K->OUT;
	$SQL  = $K->SQL;

	$TPL->block = new Dragonfly_Blocks_Block();

	$blocks = array();
	$result = $SQL->query('SELECT bid id, bkey, title label, url, bposition, weight, active, blanguage, blockfile, view
	FROM '.$SQL->TBL->blocks.' ORDER BY title');
	while ($row = $result->fetch_assoc()) {
		if (defined($row['label'])) { $row['label'] = constant($row['label']); }
		$blocks[$row['id']] = $row;
	}

	#
	# javascript blocks table
	#
	$blocks_list = Blocks::list_all();
	$TPL->modules = array('active'=>array(),'inactive'=>array());
	$TPL->modules_blocks = array();
	foreach ($blocks_list as $modname => $module)
	{
		$module['blocks'] = intval($module['blocks']);

		$sides = array('l'=>array(), 'c'=>array(), 'd'=>array(), 'r'=>array());
		foreach ($module as $bid => $location) {
			if (!intval($bid) || empty($blocks[$bid])) continue;
			$sides[$location][] = array(
				'id'     => $bid,
				'label'  => $blocks[$bid]['label'],
				'weight' => count($sides[$location]),
			);
		}

		if (defined($module['title'])) { $module['title'] = constant($module['title']); }

		$TPL->modules_blocks[] = array(
			'id'     => $module['mid'],
			'label'  => $module['title'],
			'active' => $L10N->get((-1 == $module['mid'] || is_active($modname)) ? 'yes' : 'no'),
			'blocks' => $sides,
			'blocks_l' => !!($module['blocks'] & Blocks::LEFT),
			'blocks_r' => !!($module['blocks'] & Blocks::RIGHT),
			'blocks_c' => !!($module['blocks'] & Blocks::CENTER),
			'blocks_d' => !!($module['blocks'] & Blocks::DOWN),
		);

		#
		# add new block
		#
		if ($module['mid'] == -1) continue;
		$TPL->modules[is_active($modname)?'active':'inactive'][] = array(
			'id' => $module['mid'],
			'label' => $module['title'],
		);
	}

	$groups = $TPL->block->getViewOptions();
	#
	# static blocks table
	#
	$visblocks = array();
	foreach ($blocks as $id => $block)
	{
		$visblocks[$block['blockfile']] = true;
		$block['allow_del']  = false;
		$block['language']   = ($block['blanguage'] ? $block['blanguage'] : Dragonfly::getKernel()->L10N->get('All'));
		$block['view_group'] = $groups[$block['view']]['label'];
		if ($block['bkey'] == 'admin' || $block['bkey'] == 'userbox') {
			$block['type'] = $L10N->get('System');
		} else {
			$block['allow_del'] = true;
			if ($block['bkey'] == 'custom')   { $block['type'] = 'Custom'; }
			elseif ($block['bkey'] == 'rss')  { $block['type'] = 'RSS/RDF'; }
			elseif ($block['bkey'] == 'file') { $block['type'] = $L10N->get('File'); }
		}
		$blocks[$id] = $block;
	}
	$TPL->blocks = $blocks;

	$selblocks = array();
	foreach ($TPL->block->getFileOptions() as $file) {
		if (!isset($visblocks[$file['value']])) {
			$selblocks[] = $file;
		}
	}
	$TPL->blockfiles = $selblocks;

	$TPL->headlines  = $SQL->query("SELECT hid id, sitename label FROM {$SQL->TBL->headlines}");

	$TPL->display('admin/blocks/index');
}

function block_show($bid)
{
	global $Blocks, $cpgtpl;
	Blocks::$showblocks = 0;
	require('header.php');
	$block = new Dragonfly_Blocks_Block($bid);
	$cpgtpl->assign_vars(array(
		'U_CHANGE' => URL::admin('blocks&amp;change='.$block->bid),
		'U_EDIT' => URL::admin('blocks&amp;edit='.$block->bid),
		'U_DEL' => empty($block->bkey) ? '' : URL::admin('blocks&amp;del='.$block->bid),
		'S_BID' => $block->bid)
	);
	$Blocks->preview($block->data);
}

function BlocksEdit($bid)
{
	Dragonfly_Page::setTitle(Dragonfly::getKernel()->L10N->get('Edit Block'));

	Dragonfly_Output_Js::add('includes/poodle/javascript/bbcode.js');
	Dragonfly_Output_Css::add('bbcode');

	$TPL = Dragonfly::getKernel()->OUT;
	$SQL = Dragonfly::getKernel()->SQL;

	$TPL->block = new Dragonfly_Blocks_Block($bid);
	$bid = $TPL->block->bid;

	$blocks_list = Blocks::list_all();
	$TPL->modules = array('active'=>array(),'inactive'=>array());
	foreach ($blocks_list as $modname => $module)
	{
		if ($module['mid'] == -1) continue;
		$TPL->modules[is_active($modname)?'active':'inactive'][] = array(
			'id' => $module['mid'],
			'label' => defined($module['title']) ? constant($module['title']) : $module['title'],
			'selected' => isset($module[$bid]),
		);
	}

	$TPL->blockfiles = $TPL->block->getFileOptions();

	return $TPL->display('admin/blocks/edit');
}

function BlocksEditSave($bid)
{
	$SQL = Dragonfly::getKernel()->SQL;

	$block = new Dragonfly_Blocks_Block($bid);
	$bid   = $block->bid;
	foreach ($_POST['block'] as $k => $v) { $block->$k = $v; }

	if (!empty($_POST['headline']) && $headline = intval($_POST['headline'])) {
		list($block->title, $block->url) = $SQL->uFetchRow("SELECT sitename, headlinesurl FROM {$SQL->TBL->headlines} WHERE hid={$headline}");
	}

	if (!$block->save()) {
		return false;
	}

	$in_modules = array();
	$count = empty($_POST['in_module']) ? 0 : count($_POST['in_module']);
	for ($i=0; $i<$count; ++$i) {
		if ($mid = intval($_POST['in_module'][$i])) {
			$in_modules[$mid] = 1;
		}
	}

	if (!empty($in_modules))
	{
		if ($bid)
		{
			$result = $SQL->query("SELECT
				a.mid,
				b.bid,
				MAX(a.weight)
			FROM {$SQL->TBL->blocks_custom} a
			LEFT JOIN {$SQL->TBL->blocks_custom} b ON (b.mid=a.mid AND b.bid={$block->bid})
			GROUP BY a.mid");
		}
		else
		{
			$result = $SQL->query("SELECT
				mid,
				0,
				MAX(weight)
			FROM {$SQL->TBL->blocks_custom}
			WHERE mid IN (".implode(',', array_keys($in_modules)).")
			GROUP BY mid");
		}
		while ($row = $result->fetch_row()) {
			if (isset($in_modules[$row[0]])) {
				if ($row[1]) {
					# module id has been posted and it exists within the table: clearing posteded data
					unset($in_modules[$row[0]]);
				} else {
					# save what we need for later use
					$in_modules[$row[0]] = $row[2]+1;
				}
			} else {
				# block is there but module id has not been posted so delete from it
				$SQL->exec("DELETE FROM {$SQL->TBL->blocks_custom} WHERE bid={$block->bid} AND mid=".$row[0]);
				$SQL->exec("UPDATE {$SQL->TBL->blocks_custom} SET weight=weight-1 WHERE weight>{$row[2]} AND mid=".$row[0]);
			}
		}
		if (!empty($in_modules)) {
			foreach ($in_modules as $mid => $pos) {
				$in_modules[$mid] = "({$block->bid}, {$mid}, '{$block->bposition}', {$pos})";
			}
			$SQL->exec("INSERT INTO {$SQL->TBL->blocks_custom} (bid, mid, side, weight) VALUES ".implode(',', $in_modules));
		}
	}

	//Dragonfly::getKernel()->CACHE->delete('blocks_list');
	URL::redirect(URL::admin('blocks'));
}
